package org.leviatan.dataharbour.core;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

/**
 * This class represents a configuration of DataHarbour. Every instance of
 * DataHarbour runs with one DataHarbourConfiguration loaded. To start an instance
 * of DataHarbour first setup and initialize this class. And then use it to start
 * a new instance of DataHarbour.
 * 
 * @author Leviatan
 *
 */
public abstract class DataHarbourConfiguration {
	
	private static Properties props = new Properties();
	
	
	/**
	 * The absolute path to the directory where DataHarbour will store it's
	 * register data.
	 */
	public static String pathRegister = null;
	
	public static String subPathDataEntities = null;
	public static String subPathHarbourRequests = null;
	
	
	///////////////////////////////////////////////////////////////////////////
	// Model file names
	///////////////////////////////////////////////////////////////////////////
	
	
	/**
	 * The file name to use for storing register's DataSources.
	 */
	public static String modelFileNameDataSources = null;
	//public static String regHarbourRequestsFileName = null;
	
	/**
	 * The file name to use for storing register's PersistenceResources.
	 */
	public static String modelFileNamePersistenceResources = null;
	
	/**
	 * The file name to use for storing register's senders.
	 */
	public static String modelFileNameSenders = null;	

	

	
	///////////////////////////////////////////////////////////////////////////
	// List file names
	///////////////////////////////////////////////////////////////////////////
	
	public static String listFileNameHarbourRequestIds = null;
	
	/**
	 * The file name to use for storing register's unpersisted HarbourRequests.
	 */
	public static String listFileNameUnpersistedHarbourRequestIds = null;
	
	public static String listFileNameDataEntityIds = null;
	
	
	///////////////////////////////////////////////////////////////////////////
	// Mapping file names
	///////////////////////////////////////////////////////////////////////////
	
	/**
	 * The file name to use for storing register's sender id to DataSources
	 * mappings.
	 */
	public static String mapFileNameSender2DataSources = null;
	
	public static String mapFileNameSender2HarbourRequest = null;
	
	/**
	 * The file name to use for storing register's DataSource to
	 * PersistenceResources mappings.
	 */
	public static String mapFileNameDataSource2PersistenceResources = null;
	
	/**
	 * The file name to use for storing register's DataSource to Definator
	 * structures.
	 */
	public static String mapFileNameDataSource2DefinatorTables = null;
	
	/**
	 * The file name to use for storing register's HarbourRequest to
	 * Definator structure mappings.
	 */
	public static String mapFileNameDataEntity2DefinatorFields = null;
	
	public static String mapFileNameHarbourRequest2DataEntities = null;
	
	
	
	
	
	/**
	 * The directory path to the log4j configuration file.
	 */
	public static String pathLogConf = null;
	
	/**
	 * The file name of the log4j configuration file.
	 */
	public static String logConfFileName = null;
	
	/**
	 * Log4j logging level to use.
	 */
	public static String logLevel = null;
	
	/**
	 * The file name of the java property file to use when initializing this
	 * configuration.
	 */
	private static String propsFileName = "dataharbour.properties";
	
	/**
	 * The directory path to the the java property file.
	 */
	private static String pathProps = "";
	
	
	
	
	
	private static FileInputStream fis 		= null;
	private static BufferedInputStream bis 	= null;
	
	private static FileOutputStream fos 	= null;
	private static BufferedOutputStream bos = null;

	
	
	
	public static void loadProperties() {
		try {
			fis = new FileInputStream(DataHarbourConfiguration.pathProps + 
					DataHarbourConfiguration.propsFileName);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		bis = new BufferedInputStream(fis);
		
		try {
			props.load(bis);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try 
		{
			bis.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try {
			fis.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		loadPropsIntoVariables();
	}
	
	public static void loadConfiguration(String confFilePath, String confFileName) {
		pathProps = confFilePath;
		propsFileName = confFileName;
		loadProperties();
	}
	
	public static void saveProperties() {
		
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(DataHarbourConfiguration.pathProps + 
						DataHarbourConfiguration.propsFileName);
			BufferedOutputStream bos = new BufferedOutputStream(fos);
			
			props.store(bos, "DataHarbour configuration properties");
			props.storeToXML(bos, "DataHarbour configuration properties");
			
			fos.close();
			bos.close();
			
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
	}
	
	private static void loadPropsIntoVariables() {
		pathRegister = props.getProperty("path-register");
		
		// sub paths
		subPathHarbourRequests = props.getProperty("sub-path-harbour-requests");
		subPathDataEntities = props.getProperty("sub-path-data-entities");
		
		// model files
		modelFileNameDataSources = props.getProperty("file-name-datasources");
		modelFileNamePersistenceResources = props.getProperty("file-name-persistence-resources");
		modelFileNameSenders = props.getProperty("file-name-senders");
		
		// list files
		listFileNameHarbourRequestIds = props.getProperty("file-name-harbour-request-ids");
		listFileNameUnpersistedHarbourRequestIds = props.getProperty("file-name-unpersisted-harbour-request-ids");
		listFileNameDataEntityIds = props.getProperty("file-name-data-entity-ids");
		
		// mapping files
		mapFileNameDataSource2PersistenceResources = props.getProperty("file-name-datasource-2-persistence-resources");
		mapFileNameDataSource2DefinatorTables = props.getProperty("file-name-datasource-2-definator-tables");
		mapFileNameSender2DataSources = props.getProperty("file-name-sender-2-datasource");
		mapFileNameDataEntity2DefinatorFields = props.getProperty("file-name-data-entity-2-definator-fields");
		mapFileNameHarbourRequest2DataEntities = props.getProperty("file-name-harbour-request-2-data-entities");
		mapFileNameSender2HarbourRequest = props.getProperty("file-name-sender-2-harbour-requests");
		
		// logging
		pathLogConf = props.getProperty("path-logging-conf");
		logConfFileName = props.getProperty("file-name-logging-conf");
		logLevel = props.getProperty("logging-level");
		
	}
	
	protected void finalize() throws Throwable {
		super.finalize();
		try 
		{
			bis.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			fis.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			bos.close();
		} catch (IOException e) {
		}
		try {
			fos.close();
		} catch (IOException e) {
		}	
	}
}
